package com.yonyou.brigade.ybz.service.impl;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.rpc.RpcContext;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.yonyou.brigade.order_center.service.IBriCarOrderService;
import com.yonyou.brigade.order_center.service.IBriFlightOrderService;
import com.yonyou.brigade.order_center.service.IBriHotelOrderService;
import com.yonyou.brigade.order_center.service.IBriTrainOrderService;
import com.yonyou.brigade.util.HttpClientUtil;
import com.yonyou.brigade.ybz.model.BillInfo;
import com.yonyou.brigade.ybz.model.BriOrderNote;
import com.yonyou.brigade.ybz.model.BriOrderNoteError;
import com.yonyou.brigade.ybz.service.IBriOrderNoteErrorService;
import com.yonyou.brigade.ybz.service.IBriOrderNoteService;
import com.yonyou.brigade.ybz.service.IConvertService;
import com.yonyou.ybz.note.service.IBrigadeNoteService;
import com.yonyou.ybzboot.sysconfig.thread.InvocationInfoSetter;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * 转换平台接口调用及数据转换服务实现类
 *
 * @Auther: kfw
 * @Date: 2018/8/14 14:09
 */
@Service
@PropertySource("classpath:/config/bdsdk.properties")
public class ConvertServiceImpl implements IConvertService {
    private static final Logger logger = LoggerFactory.getLogger(ConvertServiceImpl.class);
    @Reference
    IBrigadeNoteService iBrigadeNoteService;
    /*@Autowired
    private IMailService mailService;*/

    @Value("${cnv.base.url}")
    private String cnvBaseUrl;
    @Value("${cnv.cnv.url}")
    private String cnvUrl;
    @Value("${fiClound.key.thd_secure}")
    private String fiCloud_thd_secureKey;
    @Value("${fiClound.value.thd_secure}")
    private String fiCloud_thd_secureValue;
    @Value("${fiClound.key.thd_user}")
    private String fiCloud_thd_userKey;
    @Value("${fiClound.key.thd_tenant}")
    private String fiCloud_thd_tenantKey;
    @Value("${fiClound.key.thd_app}")
    private String fiCloud_thd_appKey;
    @Value("${fiClound.value.thd_app}")
    private String fiCloud_thd_appValue;
    @Value("${cnv.brigade.flight.tradetype}")
    private String flightTradetype;
    @Value("${cnv.brigade.hotel.tradetype}")
    private String hotelTradetype;
    @Value("${cnv.brigade.train.tradetype}")
    private String trainTradetype;
    @Value("${cnv.brigade.car.tradetype}")
    private String carTradetype;


    @Autowired
    @Qualifier("briHotelOrderServiceImpl")
    private IBriHotelOrderService briHotelOrderService;

    @Autowired
    @Qualifier("briFlightOrderServiceImpl")
    private IBriFlightOrderService briFlightOrderService;

    @Autowired
    @Qualifier("briTrainOrderServiceImpl")
    private IBriTrainOrderService briTrainOrderService;

    @Autowired
    @Qualifier("briCarOrderServiceImpl")
    private IBriCarOrderService briCarOrderService;

    @Autowired
    @Qualifier("briOrderNoteServiceImpl")
    private IBriOrderNoteService briOrderNoteService;

    @Autowired
    @Qualifier("briOrderNoteErrorServiceImpl")
    private IBriOrderNoteErrorService briOrderNoteErrorService;

    /**
     * 通过HttpClient调用其他系统服务，目前主要用来向转换平台注册信息
     *
     * @param url       调用服务的URL
     * @param cookie    httpclient调用cookie,这里传入test=visible可以标识使用转换平台灰度环境
     * @param userId    用户ID
     * @param tenantId  租户ID
     * @param paramJson 调用服务所需的参数
     * @Return: boolean 调用结果
     * @Auther: kfw
     * @Date: 2018/8/21 14:14
     */
    @Override
    public Boolean cnvRegister(String url, String cookie, String userId, String tenantId, String paramJson) {
        Map<String, String> fiCloudHeader = getFiCloudHeader(userId, tenantId);
        if (StringUtils.isEmpty(paramJson)) {
            fiCloudHeader.put("Content-Type", "application/x-www-form-urlencoded");
        }
        if (StringUtils.isEmpty(userId) || StringUtils.isEmpty(tenantId)) {
            logger.info("调用其他系统时，userId或tenantId为空");
            return false;
        }
        String res = HttpClientUtil.post(url, fiCloudHeader, cookie, paramJson);
        //解析返回的json，检查result中的success，如果是true则表示成功，否则表示失败
        JSONObject jsonObject = JSONObject.parseObject(res);
        /*Boolean result = jsonObject.getBoolean("success");
        JSONObject resultJo = JSONObject.parseObject(resultStr);*/
        if (jsonObject != null && "true".equalsIgnoreCase(jsonObject.getString("success"))) {
            return true;
        } else {
            logger.info(jsonObject.getString("message"));
            return false;
        }
    }

    /**
     * 查询转换平台是否已有外部系统注册
     *
     * @param url       调用服务的URL
     * @param cookie    httpclient调用cookie,这里传入test=visible可以标识使用转换平台灰度环境
     * @param userId    用户ID
     * @param tenantId  租户ID
     * @param paramJson 调用服务所需的参数
     * @Return: boolean 调用结果
     * @Auther: kfw
     * @Date: 2018/8/21 14:14
     */
    @Override
    public Boolean query(String url, String cookie, String userId, String tenantId, String paramJson) {
        Map<String, String> fiCloudHeader = getFiCloudHeader(userId, tenantId);
        if (StringUtils.isEmpty(userId) || StringUtils.isEmpty(tenantId)) {
            logger.info("调用其他系统时，userId或tenantId为空");
            return false;
        }
        String res = HttpClientUtil.post(url, fiCloudHeader, cookie, paramJson);
        JSONObject jsonObject = JSONObject.parseObject(res);
        if (jsonObject != null && StringUtils.isNotEmpty(jsonObject.getString("num"))
                && 0 < jsonObject.getInteger("num")) {
            return true;
        } else {
            logger.info(jsonObject.getString("message"));
            return false;
        }
    }

    /**
     * 通过HttpClient调用转换平台转换数据
     *
     * @param billtypeCode 交易类型，源数据在转换平台注册的交易类型，与systemCode一起查询所有对应的映射规则
     * @param systemCode   系统编码，源数据所属系统在转换平台注册的编码，与billtypeCode一起查询所有对应的映射规则
     * @param cookie       httpclient调用cookie,这里传入test=visible可以标识使用转换平台灰度环境
     * @param userId       用户ID
     * @param tenantId     租户ID
     * @param billdata     源数据，要进行转换的数据
     * @Return: JSONArray 源数据经过转换后得到的数据
     * @Auther: kfw
     * @Date: 2018/8/21 14:14
     */
    @Override
    public JSONObject convert(String billtypeCode, String systemCode, String userId, String tenantId, String cookie, JSONObject billdata) {
        Map<String, String> fiCloudHeader = getFiCloudHeader(userId, tenantId);
        fiCloudHeader.put("Content-Type", "application/x-www-form-urlencoded");
        BillInfo billinfo = new BillInfo();
        billinfo.setReqid(UUID.randomUUID().toString());
        billinfo.setAction("add");
        if (!StringUtils.isEmpty(billdata.getString("orderId")) && !StringUtils.isEmpty(billdata.getString("passengerStaffNo")) && !StringUtils.isEmpty(billdata.getString("tradeTime"))) {
            billinfo.setBillid(billdata.getString("orderId") + "_" + billdata.getString("passengerStaffNo"));
        } else if (StringUtils.isEmpty(billdata.getString("orderId"))) {
            billinfo.setBillid(UUID.randomUUID().toString());
        } else {
            billinfo.setBillid(billdata.getString("orderId"));
        }
        billinfo.setBilltypecode(billtypeCode);
        billinfo.setSystemcode(systemCode);

        Map<String, String> param = new HashMap<>();
        param.put("billinfo", JSON.toJSONString(billinfo));
        param.put("billdata", billdata.toJSONString());
        logger.info("请求转换平台 param>>>" + JSONObject.toJSONString(param) );
        String res = HttpClientUtil.postForm(cnvBaseUrl + cnvUrl, fiCloudHeader, cookie, param);
        logger.info("请求转换平台结果>>>" + res);
        if (StringUtils.isEmpty(res)){
            logger.info("转换结果异常");
            JSONObject rs = new JSONObject();
            rs.put("success", false);
            return rs;
        }
        JSONObject resultJson = JSONObject.parseObject(res).getJSONObject("result");
        if (resultJson != null && "true".equalsIgnoreCase(resultJson.getString("success"))) {
            return resultJson;
        } else {
            logger.info("转换平台异常：" + res);
            return JSONObject.parseObject(res);
        }
    }

    @Override
    public void pushToYBZ(Map<String, List<Map<String, Object>>> noteMap, String userid, String tenant, String tradeType, String orderId) {
        if (noteMap.isEmpty()) {
            logger.error("定时任务机票订单转换推送友报账出错，转换平台转换错误！");
            // 发送邮件提醒
            return;
        }
        try {
            InvocationInfoSetter.setInvocationInfo4rpc(tenant);
//            RpcContext.getContext().getAttachments().put("tenantid", tenant);
            logger.info("推送给报账生成记事的数据=============noteMap为" + JSON.toJSONString(noteMap) + "; userId为" + userid + "; tenant为" + tenant );
            Map pushResult = iBrigadeNoteService.saveNoteList(noteMap, userid, tenant);
            logger.info("推送数据是否成功=======================" + pushResult.toString());
            if (!(Boolean) pushResult.get("success")) {
                logger.info("推送数据失败=======================" + pushResult.toString());
                logger.info(pushResult.toString());
                BriOrderNoteError briOrderNoteError = new BriOrderNoteError();
                String information = pushResult.get("information") == null ? "" : pushResult.get("information").toString();
                if (information.length() > 1000) {
                    information = information.substring(0, 1000);
                }
                briOrderNoteError.setError(information);
                briOrderNoteError.setOrderId(orderId);
                briOrderNoteError.setOrderType(tradeType);
                briOrderNoteErrorService.insert(briOrderNoteError);
                //发送邮件提醒
            } else {
                Map<String, List> data = (Map) pushResult.get("data");
                if (data != null && data.size() > 0) {
                    for (Map.Entry<String, List> entry : data.entrySet()) {
                        String key = entry.getKey();
                        List<String> value = entry.getValue();
                        if (value != null && value.size() > 0) {

                            if (tradeType.equals(hotelTradetype)) {
                                briHotelOrderService.updateIsNoteByOrderId(Integer.parseInt(key));
                            } else if (tradeType.equals(flightTradetype)) {
                                briFlightOrderService.updateIsNoteByOrderId(Integer.parseInt(key));
                            } else if (tradeType.equals(trainTradetype)) {
                                briTrainOrderService.updateIsNoteByOrderId(Integer.parseInt(key));
                            } else if (tradeType.equals(carTradetype)) {
                                briCarOrderService.updateIsNoteByOrderId(Integer.parseInt(key));
                            }


                            BriOrderNote briOrderNote = new BriOrderNote();
                            briOrderNote.setNotePk(value.get(0).split(",")[0]);
                            briOrderNote.setNoteType(value.get(0).split(",")[1]);
                            briOrderNote.setOrderId(String.valueOf(key));
                            briOrderNote.setOrderType(tradeType);
                            briOrderNoteService.insert(briOrderNote);
                        }

                    }
                }

            }

        } catch (Exception e) {
            logger.error("定时任务订单转换记事推送友报账出错，" + e.getMessage());
            // 发送邮件提醒
        }
    }

    /**
     * 组装HTTPClient请求的header
     *
     * @param userId   用户ID
     * @param tenantId 租户ID
     * @Return: Map<String, String> 组装后的header
     * @Auther: kfw
     * @Date: 2018/8/21 14:26
     */
    private Map<String, String> getFiCloudHeader(String userId, String tenantId) {
        Map<String, String> fiCloudHeader = new HashMap<>();
        fiCloudHeader.put(fiCloud_thd_secureKey, fiCloud_thd_secureValue);
        fiCloudHeader.put(fiCloud_thd_appKey, fiCloud_thd_appValue);
        fiCloudHeader.put(fiCloud_thd_userKey, userId);
        fiCloudHeader.put(fiCloud_thd_tenantKey, tenantId);
        return fiCloudHeader;
    }
}
